
import { PacketMode } from "../Enums/PacketMode";
import { PacketRuler } from "../../Crypto/PacketRuler";
import { Cryptogram } from "../../Crypto/Cryptogram";
import { CryptoUtility } from "../../Crypto/CryptoUtility";


export class Encrypter
{
    public static ClassName:string = "Encrypter";
    private privateKey:string;
    private agentKey:string;
    private broadcastKey:string;
    
    public isTrace:boolean = false;
    public tracePacketIDs:Array<number>=[];

    private ruler:PacketRuler;
    private keyIDs:{[key:string]:any;};
    public constructor()
    {
        this.keyIDs = {};
        this.ruler = new PacketRuler();
    }
    //<summary>-----------------------------------------------------------------------------
    // Web 数据加解密
    //</summary>-----------------------------------------------------------------------------
    public EncodeWebData(data:any, sn:number=1):string{return Cryptogram.EncodeWebData(data,sn);}
    public DecodeWebData(data:string):any{return Cryptogram.DecodeWebData(data);}
    //<summary>-----------------------------------------------------------------------------
    // Socket 数据加解密
    //</summary>-----------------------------------------------------------------------------
    public EncodeSocketData(packetID:number, data:any, sn:number=1):any
    {
        var isGenDynamicKey:boolean = this.ruler.IsNeetGenDynamicKey(packetID,PacketMode.Send);
        var isNeedCompress:boolean = this.ruler.IsNeedCompressPacket(packetID,PacketMode.Send);
        var CKey:string = isGenDynamicKey?null:this.ruler.GetPacketCKey(packetID,PacketMode.Send);
        if(this.isTrace)
        {
            if(this.tracePacketIDs.indexOf(packetID)!=-1)
                console.log("[发送加密数据]===>0x"+packetID.toString(16),"GenDynamicKey:",isGenDynamicKey,"NeedCompress:",isNeedCompress,"CKey:",CKey);
        }
        return Cryptogram.EncodeSocketData(packetID,data,isGenDynamicKey,CKey,sn);
    }

    // public GetSocketDatas(bytes:any):Array<Array<number>>{return Cryptogram.GetSocketDatas(bytes);}
    public GetPacketID(data:any):number{return Cryptogram.GetPacketID(data);}
    public DecodeSocketData(data:any):any
    {
        var packetID:number = this.GetPacketID(data);
        var isGenDynamicKey:boolean = this.ruler.IsNeetGenDynamicKey(packetID,1);
        var isNeedDecompress:boolean = this.ruler.IsNeedDecompressPacket(packetID,1);
        var CKey:string = isGenDynamicKey?null:this.ruler.GetPacketCKey(packetID,1);        
        if(this.isTrace)
        {
            if(this.tracePacketIDs.indexOf(packetID)!=-1)
                console.log("[接收解密数据]===>0x"+packetID.toString(16),"GenDynamicKey:",isGenDynamicKey,"NeedDecompress:",isNeedDecompress,"CKey:",CKey);
        }
        return Cryptogram.DecodeSocketData(data,isGenDynamicKey,isNeedDecompress,CKey);
    }
    public GetString(value:any):String{return CryptoUtility.GetString(value);}








    public set AgentKey(value:string){this.agentKey = value;}
    public set BroadcastKey(value:string){this.broadcastKey = value;}
    public set PrivateKey(value:string){this.privateKey = value;}
    public SetAgentKeyPacketID(packetID:number, packetMode:PacketMode):void{this.setDictPacketID("A",packetID,packetMode);}
    public SetBroadcastKeyPacketID(packetID:number, packetMode:PacketMode):void{this.setDictPacketID("B",packetID,packetMode);}
    public SetPrivateKeyPacketID(packetID:number, packetMode:PacketMode):void{this.setDictPacketID("P",packetID,packetMode);}
    private setDictPacketID(flag:string,packetID:number, packetMode:PacketMode):void
    {
        if(!this.keyIDs[flag])this.keyIDs[flag] = {};
        if(!this.keyIDs[flag][packetMode])this.keyIDs[flag][packetMode] = [];
        let packets:Array<number> = this.keyIDs[flag][packetMode];
        if(packets.indexOf(packetID)==-1)packets.push(packetID);
    }
    public get Ruler():PacketRuler{return this.ruler;}
    
    public flush():void
    {
        this.ruler.ClearPacketKeys();
        this.updateKeyIDs("A",this.agentKey);
        this.updateKeyIDs("B",this.broadcastKey);
        this.updateKeyIDs("P",this.privateKey);
    }
    private updateKeyIDs(flag:string,key:string):void
    {
        if(key==null||key=="")return;
        let o = this.keyIDs[flag];
        if(o==null)return;
        let sendIDs:Array<number> = o[PacketMode.Send];
        if(sendIDs!=null)
        {
            for(let i:number = 0;i<sendIDs.length;i++)
                this.ruler.SetPacketKey(key,sendIDs[i],PacketMode.Send);
        }
        let recIDs:Array<number> = o[PacketMode.Receive];
        if(recIDs!=null)
        {
            for(let j:number = 0;j<recIDs.length;j++)
                this.ruler.SetPacketKey(key,recIDs[j],PacketMode.Receive);
        }
    }
}
